#include "aliyun.h"

/*文件内部使用的宏*/
//MQTT服务器的domain地址
#define ALIYUN_SERVER "a1ay7f9DL7I.iot-as-mqtt.cn-shanghai.aliyuncs.com"
//MQTT服务器的port端口
#define ALIYUN_PORT 1883
//client端标识符
#define MQTT_CLIENT_ID "12345|securemode=3,signmethod=hmacsha1|"
//用户账号
#define MQTT_USERNAME "ESP32_LED&a1ay7f9DL7I"
//用户密码
#define MQTT_PASSWORD "0922F148DAAA0E418ED49533979B0240603CDBD5"
//阿里云设备上报属性请求Topic
#define ALIYUN_UPDATE_TOPIC "/sys/a1ay7f9DL7I/ESP32_LED/thing/event/property/post"
//阿里云设备上报属性响应Topic
#define ALIYUN_UPDATE_REPLY "/sys/a1ay7f9DL7I/ESP32_LED/thing/event/property/post_reply"
//阿里云设备设置属性请求Topic
#define ALIYUN_SET "/sys/a1ay7f9DL7I/ESP32_LED/thing/service/property/set"

/*本地变量*/
WiFiClient espclient;
static bool connect_to_aliyun_flag = false;//连接到阿里云物联网平台标志 false--未连接 true--连接

/*全局变量*/
PubSubClient client(espclient);
extern volatile bool nightled_flag;//WS2812BLED呼吸灯开关标志 false--关闭 ture--开启
extern volatile uint8_t led_switch;//控制led灯带开关 0--关灯 1--开灯
extern volatile uint8_t led_ctrl_idx;//控制WS2812B的色彩 0~8
extern volatile uint8_t WS2812B_brightness;//控制WS2812B的亮度 0~255
extern volatile uint8_t water_switch;//雾化器开关标志 0--关闭 1--开启

/*静态函数*/
//回调函数
static void callback(char *topic,uint8_t *payload,unsigned int length)
{
    if(strcmp(topic,ALIYUN_UPDATE_REPLY) == 0)//接收到阿里云设备上报属性响应Topic
    {

    }
    else if(strcmp(topic,ALIYUN_SET) == 0)//接收到阿里云设备设置属性请求Topic
    {
        char str[200];
        memset(str,'\0',sizeof(str));
        //Serial.printf("str:%s\r\n",str);
        //char *ret = strstr((const char *)payload,"WS2812B_Color");
        //Serial.println(ret);
        //Serial.println(length);
        for(uint8_t i = 0; i < length; i++)
        {
            str[i] = (char)payload[i];
            //Serial.print((char)payload[i]);
        }
        //Serial.printf("%s\r\n",str);

        //WS2812B灯带
        if(strstr(str,"WS2812B_Color") != NULL)
        {
            strcpy(str,strstr(str, "WS2812B_Color"));
            nightled_flag = false;//关闭WS2812B呼吸灯

            switch (str[15])
            {
                case 49://1
                {
                    led_ctrl_idx = 0;
                    WS2812B_SetGRB(120, 10, 0);
                    //Serial.println("0 color");
                    Update_WS2812B_Color_To_Aliyun(1);
                    break;
                }

                case 50:
                {
                    led_ctrl_idx = 1;
                    WS2812B_SetGRB(70, 150, 255);
                    //Serial.println("1 color");
                    Update_WS2812B_Color_To_Aliyun(2);
                    break;
                }

                case 51:
                {
                    led_ctrl_idx = 2;
                    WS2812B_SetGRB(80, 40, 240);
                    Update_WS2812B_Color_To_Aliyun(3);
                    //Serial.println("2 color");
                    break;
                }

                case 52:
                {
                    led_ctrl_idx = 3;
                    WS2812B_SetGRB(0, 100, 50);
                    Update_WS2812B_Color_To_Aliyun(4);
                    //Serial.println("3 color");
                    break;
                }

                case 53:
                {
                    led_ctrl_idx = 4;
                    WS2812B_SetGRB(90, 0, 30);
                    Update_WS2812B_Color_To_Aliyun(5);
                    //Serial.println("4 color");
                    break;
                }

                case 54:
                {
                    led_ctrl_idx = 5;
                    WS2812B_SetGRB(30, 60, 100);
                    Update_WS2812B_Color_To_Aliyun(6);
                    //Serial.println("5 color");
                    break;
                }

                case 55:
                {
                    led_ctrl_idx = 6;
                    WS2812B_SetGRB(160, 80, 0);
                    Update_WS2812B_Color_To_Aliyun(7);
                    //Serial.println("6 color");
                    break;
                }

                case 56:
                {
                    led_ctrl_idx = 7;
                    nightled_flag = true;//打开WS2812B呼吸灯
                    Update_WS2812B_Color_To_Aliyun(8);
                    //Serial.println("Close");
                    break;
                }

                case 48:
                {
                    WS2812B_Close();
                    Update_WS2812B_Color_To_Aliyun(0);
                    break;
                }
                default:
                {
                    Serial.println(str[15]);
                    break;
                }
            }
        }
        else if(strstr(str,"LEDSwitch") != NULL)//LED灯带开关
        {
            strcpy(str,strstr(str, "LEDSwitch"));
            switch(str[11])
            {
            case 48:
            {
                led_switch = 0;
                Led_Close();
                Update_LED_Switch_To_Aliyun(0);
                break;
                
            }

            case 49:
            {
                led_switch = 1;
                Led_Open();
                Update_LED_Switch_To_Aliyun(1);
                break;
            }

            default:
            {
                Serial.println(str[11]);
                break;
            }
            }
            //Serial.println(str);
        }
        else if(strstr(str,"WS2812B_brightness") != NULL)//WS2812B亮度
        {
            String num;
            strcpy(str,strstr(str, "WS2812B_brightness"));
            if(str[23] == '}')//三位数的亮度
            {
                num += str[20];
                num += str[21];
                num += str[22];

                WS2812B_SetBrightness(num.toInt());//设置灯带亮度
                Update_WS2812B_Brightness_To_Aliyun(WS2812B_brightness);

                
                //sprintf(str1,"%c%c%c",str[20],str[21],str[22]);
                //num.
                //Serial.printf("%c%c%c",str[20], str[21], str[22]);
                //num = str[20] + str[21];
            }
            else if(str[22] == '}')//两位数的亮度
            {
                num += str[20];
                num += str[21];

                WS2812B_SetBrightness(num.toInt());
                Update_WS2812B_Brightness_To_Aliyun(WS2812B_brightness);

            }
            else if(str[21] == '}')//一位数的亮度
            {
                num += str[20];

                WS2812B_SetBrightness(num.toInt());
                Update_WS2812B_Brightness_To_Aliyun(WS2812B_brightness);
            }
        }
        else if(strstr(str,"Humidified") != NULL)//雾化器开关
        {
            strcpy(str,strstr(str, "Humidified"));
            if(str[12] == '1')
            {
                Atomizer_Open();
                water_switch = 1;
            }
            else if(str[12] == '0')
            {
                Atomizer_Close();
                water_switch = 0;
                //Update_Humidified_To_Aliyun(0);
            }
            Update_Humidified_To_Aliyun(water_switch);
        }
        else
        {
            Serial.println("haha");
            //Serial.println(str);
        }
        //if(strcpy(str,strstr(str, "WS2812B_Color")))
        //Serial.printf("%d,%s\r\n",strlen(str),str);

        //Serial.printf("%s\r\n",strchr((const char *)payload,"WS2812B_Color"));
        //Serial.printf("%s\r\n",ret); 

        // Serial.printf("\r\n%c\r\n",payload[83]);
        
        
    }
    else
    {
        //Serial.println(topic);
    }

    
}

/*全局函数*/

void Connect_To_Aliyun(void)
{
    Serial.println("Enter Connect_To_Aliyun");
    client.setServer(ALIYUN_SERVER,ALIYUN_PORT);
    while(!client.connect(MQTT_CLIENT_ID,MQTT_USERNAME,MQTT_PASSWORD))//这里可能会延迟，要考虑一下看门狗复位的因素，尽量加一下看门狗时间
    {
        Serial.println("No connect to Aliyun...");
    }

    connect_to_aliyun_flag = true;

    client.subscribe(ALIYUN_SET);
    client.setCallback(callback);


    Serial.println("\r\nConnect To aliyun success");
    Serial.printf("Aliyun.cpp %d:%d\r\n",__LINE__,esp_get_free_heap_size());
    // client.connect(MQTT_CLIENT_ID,MQTT_USERNAME,MQTT_PASSWORD);
    // if(client.connected())
    // {
    //     Serial.println("client connects Aliyun success first");
    //     Serial.printf("ESP32 HEAP:%d\r\n",esp_get_free_heap_size());
    // }
    // else
    // {
        
    // }
}

void Aliyun_Loop(void)
{
    // if(client.connected())
    // {
    //     client.loop();
    // }
    if(connect_to_aliyun_flag == true)
    {
        client.loop();
    }
    //Serial.printf("ESP32 HEAP:%d\r\n",esp_get_free_heap_size());
}

void Disconnect_To_Aliyun(void)
{
    if(connect_to_aliyun_flag == true)
    {
        client.disconnect();
        Serial.println("Disconnect To Aliyun success");
        Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        connect_to_aliyun_flag = false;
    }
}

void Update_Id_Ssid_Macaddress_To_Aliyun(IPAddress ip,String ssid,String macaddress)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[200];
        char jsonbuf[400];

        sprintf(param,"{\"IPAddress\":{\"value\":\"%s\"},\"WifiName\":{\"value\":\"%s\"},\"MACAddress\":{\"value\":\"%s\"}}",ip.toString().c_str(), 
                                                                                                                            ssid.c_str(), macaddress.c_str());
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        // Serial.println(param);
        // Serial.println(jsonbuf);
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("publish IP SSId MacAddress to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish IP and SSID to aliyun fail");
        }
    }
}

void Update_WS2812B_Color_To_Aliyun(uint8_t led_ctrl_idx)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[100];
        char jsonbuf[200];

        sprintf(param,"{\"WS2812B_Color\":{\"value\":%d}}",led_ctrl_idx);
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("\r\npublish WS28128B_Color to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish WS28128B_Color to aliyun fail");
        }
    }
}

void Update_LED_Switch_To_Aliyun(uint8_t led_switch)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[100];
        char jsonbuf[200];

        sprintf(param,"{\"LEDSwitch\":{\"value\":%d}}",led_switch);
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("\r\npublish LED_Switch to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish LED_Switch to aliyun fail");
        }
    }
}

void Update_WS2812B_Brightness_To_Aliyun(uint8_t WS2812B_brightness)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[100];
        char jsonbuf[200];

        sprintf(param,"{\"WS2812B_brightness\":{\"value\":%d}}",WS2812B_brightness);
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("\r\npublish WS2812B_Brightness to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish WS2812B_Brightness to aliyun fail");
        }
    }
}

void Update_PPB_CH2O_To_Aliyun(int ppb, float ch2o)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[100];
        char jsonbuf[200];

        sprintf(param,"{\"ppb\":{\"value\":%d},\"HCHO\":{\"value\":%f}}",ppb, ch2o);
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("\r\npublish PPB_CH2O to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish PPB_CH2O to aliyun fail");
        }
    }
}

void Update_PM25_To_Aliyun(float pm25)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[100];
        char jsonbuf[200];

        sprintf(param,"{\"PM25\":{\"value\":%f}}",pm25);
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("\r\npublish PM25 to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish PM25 to aliyun fail");
        }
    }
}

void Update_Humidified_To_Aliyun(uint8_t water_switch)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[100];
        char jsonbuf[200];

        sprintf(param,"{\"Humidified\":{\"value\":%d}}",water_switch);
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("\r\npublish Humidified to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish Humidified to aliyun fail");
        }
    }
}

void Update_Temp_Humi_To_Aliyun(char *temp, char *humi)
{
    if(connect_to_aliyun_flag == true)
    {
        char param[100];
        char jsonbuf[200];

        sprintf(param,"{\"Temp\":{\"value\":%s},\"Humi\":{\"value\":%s}}",temp,humi);
    
        sprintf(jsonbuf,"{\"id\":\"ESP8266\",\"version\":\"1.0\",\"method\":\"thing.event.property.post\",\"params\":%s}",param);
  
        if(client.publish(ALIYUN_UPDATE_TOPIC,jsonbuf))
        {
            Serial.println("\r\npublish Temp_Humi to Aliyun success");
            Serial.printf("Aliyun.cpp %d:ESP32 HEAP:%d\r\n",__LINE__,esp_get_free_heap_size());
        }
        else
        {
            Serial.println("publish Temp_Humi to aliyun fail");
        }
    }
}

